package com.block.source.utils;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.block.common.util.AESUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

/**
 * 加解密工具类
 *
 * @author lz
 * @date 2024/3/1
 */
public class JyhDsAESUtils {
    public static final String KEY = "G76DON9BRXHZAH6GHFDMT5OCXUWACZVC";
    public static final String IV = "5129844580158042";
    /**
     * 参数key和value的连接符
     */
    public static final String KEY_VALUE_JOIN = "=";
    /**
     * 两个参数的连接符
     */
    public static final String PARAM_JOIN = "&";


    /**
     * 参数签名
     *
     * @param params    请求参数
     * @param secretKey 密钥
     * @return 签名
     * @date 2024/3/1
     */
    public static String sign(Map<String, Object> params, String secretKey) {
        TreeMap<String, Object> treeMap = new TreeMap<>();
        for (String str : params.keySet()) {
            Object value = params.get(str);
            if (value == null) {
                continue;
            }
            treeMap.put(str, value);
        }
        String joinStr = JyhDsAESUtils.join(treeMap);
        String signStr = String.format("%s&secretKey=%s", joinStr,
                secretKey);
        System.out.println("签名明文=" + signStr);
        return SecureUtil.md5(signStr);
    }

    /**
     * 验证签名
     *
     * @param sign      签名
     * @param objJson   请求参数
     * @param secretKey 密钥
     * @return true/false
     * @date 2024/3/1
     */
    public static boolean verify(String sign, JSONObject objJson, String
            secretKey) {
        objJson.remove("sign");
        String tmpSign = JyhDsAESUtils.sign(objJson, secretKey);
        System.out.println("签名密文=" + tmpSign);
        return sign.equals(tmpSign);
    }

    /**
     * 字段拼接
     *
     * @param treeMap 排序后的请求参数
     * @return 字符串
     * @date 2024/3/1
     */
    private static String join(Map<String, Object> treeMap) {
        if (treeMap == null || treeMap.size() == 0) {
            return StringUtils.EMPTY;
        }
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, Object> paramKeyAndValue : treeMap.entrySet()) {
            builder.append(paramKeyAndValue.getKey()).append(KEY_VALUE_JOIN);
            builder.append(paramKeyAndValue.getValue()).append(PARAM_JOIN);
        }
        return builder.substring(0, builder.length() - 1);
    }

    public static void main(String[] args) throws Exception {
        System.out.println("======== 模拟撞库加密 ========");
        String s = UUID.randomUUID().toString();
        String reqStr = JyhDsAESUtils.encryptTest(s);
        System.out.println("\n");
        System.out.println("======== 模拟撞库解密 ========");
        JyhDsAESUtils.decryptTest(reqStr);

        System.out.println("==============================================================");

        System.out.println("======== 模拟进件加密 ========");
        String reqStr1 = JyhDsAESUtils.encryptTest1(s);
        System.out.println("\n");
        System.out.println("======== 模拟进件解密 ========");
        JyhDsAESUtils.decryptTest1(reqStr1);
    }

    private static String encryptTest(String uuid) {
        Map<String, Object> bizParams = new HashMap<>();
        bizParams.put("mobileMd5", "3522c919948719af63306cb14a9ccc83");
        bizParams.put("cityName", "北京市");
        bizParams.put("cityCode", "110100");
        bizParams.put("age", 30);
        bizParams.put("loanAmount", "10000");
        bizParams.put("sex", 1);
        bizParams.put("hasHouse", 1);
        bizParams.put("hasCar", 1);
        bizParams.put("hasCompany", 1);
        bizParams.put("hasInsurance", 1);
        bizParams.put("hasSocial", 1);
        bizParams.put("hasFund", 0);
        bizParams.put("zmfScore", "0");
        String bizJson = JSONObject.toJSONString(bizParams);
        String bizStr = AESUtil.encryptBase64(bizJson, KEY, IV);
        System.out.println("加密后的业务请求参数(data)=" + bizStr);
        String reqNo = uuid;
        String timestamp = String.valueOf(System.currentTimeMillis());
        Map<String, Object> reqParams = new HashMap<>();
        reqParams.put("reqNo", reqNo);
        reqParams.put("timestamp", timestamp);
        reqParams.put("channel", "jiqiongbao");
        reqParams.put("data", bizStr);
        String sign = JyhDsAESUtils.sign(reqParams, JyhDsAESUtils.KEY);
        reqParams.put("sign", sign);
        String jsonBody = JSONObject.toJSONString(reqParams);
        System.out.println("请求参数=" + jsonBody);
        return jsonBody;
    }

    private static String encryptTest1(String uuid) {
        Map<String, Object> bizParams = new HashMap<>();
        bizParams.put("realName", "小小张");
        bizParams.put("mobile", "13223456543");
        bizParams.put("cityName", "北京市");
        bizParams.put("cityCode", "110100");
        bizParams.put("age", 30);
        bizParams.put("clientIp", "255.255.255.3");
        bizParams.put("loanAmount", "10000");
        bizParams.put("sex", 1);
        bizParams.put("hasHouse", 1);
        bizParams.put("hasCar", 1);
        bizParams.put("hasCompany", 1);
        bizParams.put("hasInsurance", 1);
        bizParams.put("hasSocial", 1);
        bizParams.put("hasFund", 0);
        bizParams.put("zmfScore", "0");
        bizParams.put("remark", "备注");
        String bizJson = JSONObject.toJSONString(bizParams);
        String bizStr = AESUtil.encryptBase64(bizJson, KEY, IV);
        System.out.println("加密后的业务请求参数(data)=" + bizStr);
        String reqNo = uuid;
        String timestamp = String.valueOf(System.currentTimeMillis());
        Map<String, Object> reqParams = new HashMap<>();
        reqParams.put("reqNo", reqNo);
        reqParams.put("timestamp", timestamp);
        reqParams.put("channel", "jiqiongbao");
        reqParams.put("data", bizStr);
        String sign = JyhDsAESUtils.sign(reqParams, JyhDsAESUtils.KEY);
        reqParams.put("sign", sign);
        String jsonBody = JSONObject.toJSONString(reqParams);
        System.out.println("请求参数=" + jsonBody);
        return jsonBody;
    }

    private static void decryptTest(String reqStr) throws Exception {
        JSONObject objJson = JSONObject.parseObject(reqStr);
        String data = objJson.getString("data");
        String sign = objJson.getString("sign");
        boolean isSign = JyhDsAESUtils.verify(sign, objJson,
                JyhDsAESUtils.KEY);
        System.out.println("签名验证结果=" + isSign);
        if (!isSign) {
            System.out.println("签名错误");
            return;
        }
        String dataJson = AESUtil.decryptBase64(data, JyhDsAESUtils.KEY,
                JyhDsAESUtils.IV);
        System.out.println("data解密后明文=" + dataJson);
    }

    private static void decryptTest1(String reqStr) throws Exception {
        JSONObject objJson = JSONObject.parseObject(reqStr);
        String data = objJson.getString("data");
        String sign = objJson.getString("sign");
        boolean isSign = JyhDsAESUtils.verify(sign, objJson,
                JyhDsAESUtils.KEY);
        System.out.println("签名验证结果=" + isSign);
        if (!isSign) {
            System.out.println("签名错误");
            return;
        }
        String dataJson = AESUtil.decryptBase64(data, JyhDsAESUtils.KEY,
                JyhDsAESUtils.IV);
        System.out.println("data解密后明文=" + dataJson);
    }
}